#!/usr/bin/python
# -*- coding: utf-8 -*-

import socket
from os.path import expanduser
import sys
import os
import time
import errno
import threading
import subprocess
from socket import error as socket_error

class ControllerAgent:
    def __init__(self):
        self.managerIP = sys.argv[1]
        self.managerPort = int(sys.argv[2])
        # print(self.managerIP)
        # print(self.managerPort)
        self.server_address = (self.managerIP, self.managerPort)
        # Create a TCP/IP socket
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.cmd = "ls"
        self.running = True


    def connectServer(self):

        while self.running:
            try:
                # Connect the socket to the port where the server is listening
                if not self.server_address:
                    self.server_address = ('10.0.3.1', 3366)

                print('[connectServer] Connecting to %s port %s' % self.server_address)
                self.sock.connect(self.server_address)

                # Send AppAgent Message
                self.sock.send('ControllerAgent\n')
                print("[ControllerAgent] Handshaking with AgentManager...")

                # Receive OK Message
                msg = self.sock.recv(1024)
                print("[ControllerAgent] Received from AgentManager: " + msg)

                # Loop for communications with Agent Manager
                while self.running:
                    msg = self.sock.recv(1024)
                    self.dispose(msg)
            except socket_error as serr:
                if serr.errno == errno.ECONNREFUSED:
                    print("[ControllerAgent] Agent Manager is not listening")
            except:
                e = sys.exc_info()[0]
                print("[ControllerAgent] error: " + str(e))
            finally:
                time.sleep(5)

    def dispose(self, msg):
        # Receive Code
        print("ControllerAgent: " + msg)
        if "run ryu" in msg.lower():
            self.cmd = "ryu-manager --observe-links ryu.app.simple_switch_13 ryu.app.rest_topology ryu.app.ofctl_rest ryu.app.ws_topology ryu.app.gui_topology.gui_topology"
            self.runnigThread = threading.Thread(target=self.runCommand, name='runRyu')
            self.runnigThread.start()
            print("===============================run Ryu===========================")
            self.doIsListen()

        elif "stop ryu" in msg.lower():
            os.system("sudo pkill ryu-manager")
            print("===============================stop Ryu===========================")
            # self.runnigThread.join()

        elif "run floodlight" in msg.lower():
            self.cmd = "cd floodlight && java -jar target/floodlight.jar"
            self.runnigThread = threading.Thread(target=self.runCommand, name='runFloodlight')
            self.runnigThread.start()
            print("===============================run Floodligth===========================")
            self.doIsListen()

        elif "stop floodlight" in msg.lower():
            os.system("sudo pkill java")
            print("===============================stop Floodligth===========================")

        #TODO
        elif "run odl" in msg.lower():
            print("===============================run ODL===========================")
            self.doIsListen()
            pass

        elif "stop odl" in msg.lower():
            os.system("sudo pkill java")
            print("===============================stop ODL===========================")

        elif "run onos" in msg.lower():
            self.cmd = "onos-1.13.1/bin/onos-service clean debug"
            self.runnigThread = threading.Thread(target=self.runCommand, name='runONOS')
            self.runnigThread.start()
            print("===============================run ONOS===========================")
            self.doIsListen()

        elif "stop onos" in msg.lower():
            os.system("sudo pkill java")
            print("===============================stop ONOS===========================")

        elif "run pox" in msg.lower():
            #~/pox/pox.py --verbose forwarding.l2_learning
            self.cmd = "~/pox/pox.py --verbose forwarding.l2_learning"
            self.runnigThread = threading.Thread(target=self.runCommand, name='runPox')
            self.runnigThread.start()
            print("===============================run Pox===========================")
            self.doIsListen()
            pass

        elif "stop pox" in msg.lower():
            os.system("sudo pkill python")
            print("===============================stop Pox===========================")

        elif "echo" in msg.lower():
            self.sock.send('echo\n')

        elif "stop agent" in msg.lower():
            self.running = False

        else:
            print("[ControllerAgent] Don't know how to process " + msg)

    def runCommand(self):
        p = subprocess.Popen(self.cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
        out = p.stdout.readline()
        while(out):
            print(out)
            out = p.stdout.readline()

    def doIsListen(self):
        while True:
            if self.isListen():
                print "controller has start."
                break
            else:
                print "waiting controller start."
                time.sleep(5)

    def isListen(self):
        res = os.popen("sudo netstat -ap | grep 66[3,5]3")
        line = res.read()
        if "LISTEN" in line:
            self.sock.send("controller has start\n")
            return True
        return False


if __name__ == "__main__":
     if len(sys.argv) != 3:
         print ("Usage: sudo python topo-setup.py <AM_IP> <AM_PORT>")
         sys.exit(0)
     agent = ControllerAgent()
     agent.connectServer()